#include "GRectangleOriented.h"
#include "GMatrix3x3.h"
#include "GTransform2.h"

namespace GMath
{

	GRectangleOriented::GRectangleOriented()
	{
		Create(GVector2::Zero, GVector2::One, 0.0f);
	}

	GRectangleOriented::GRectangleOriented(const GVector2& Center, const GVector2& Dimension, float Rotation)
	{
		Create(Center, Dimension, Rotation);
	}

	GRectangleOriented::GRectangleOriented(const GVector2& Center, const GVector2& Dimension, const GVector2& Right, const GVector2& Up)
	{
		Create(Center, Dimension, Right, Up);
	}

	void GRectangleOriented::Create(const GVector2& TheCenter, const GVector2& TheDimension, float TheRotation)
	{
		Center = TheCenter;
		Dimension = TheDimension;

		GMatrix3x3 RotationMatrix;
		GTransform2::CreateRotation(RotationMatrix, TheRotation);

		Up = GVector2::UnitY * RotationMatrix;
		Right = GVector2::UnitX * RotationMatrix;

	}

	void GRectangleOriented::Create(const GVector2& TheCenter, const GVector2& TheDimension, const GVector2& TheRight, const GVector2& TheUp)
	{
		Center = TheCenter;
		Dimension = TheDimension;
		Right = TheRight;
		Up = TheUp;
	}

	GVector2 GRectangleOriented::GetDimension() const
	{
		return Dimension;
	}

	GVector2 GRectangleOriented::GetCenter() const
	{
		return Center;
	}

	const GVector2& GRectangleOriented::GetUp() const
	{
		return Up;
	}

	const GVector2& GRectangleOriented::GetRight() const
	{
		return Right;
	}

	float GRectangleOriented::Area() const
	{
		GVector2 Dimension = GetDimension();
		return Dimension.x * Dimension.y;
	}

	float GRectangleOriented::Circumference() const
	{
		GVector2 Dimension = GetDimension();
		return (Dimension.x + Dimension.y) * 2.0f;
	}
	
	void GRectangleOriented::GetCorners(OUTPUT GVector2 Arr[G_RC_COUNT]) const
	{
		GVector2 WidthVec(Right * Dimension.x / 2.0f);
		GVector2 HeightVec(Up * Dimension.y / 2.0f);

		Arr[G_RC_BOTTOM_LEFT]	= Center - HeightVec - WidthVec;
		Arr[G_RC_BOTTOM_RIGHT]	= Center - HeightVec + WidthVec;
		Arr[G_RC_TOP_LEFT]		= Center + HeightVec - WidthVec;
		Arr[G_RC_TOP_RIGHT]		= Center + HeightVec + WidthVec;

	}

	#define		G_BOX_X_AXIS		(GUInt32)0x01
	#define		G_BOX_Y_AXIS		(GUInt32)0x02

	GVector2 GRectangleOriented::GetCorner(GRectangleCorner Corner) const
	{
		GVector2 HalfDim = Dimension / 2.0f;
		GVector2 HalfDimVec = Up * HalfDim.y + Right * HalfDim.x;
	
		GVector2 Min = Center + HalfDimVec;
		GVector2 Max = Center - HalfDimVec;

		return GVector2(Corner & G_BOX_X_AXIS ? Max.x : Min.x,
						Corner & G_BOX_Y_AXIS ? Max.y : Min.y);
	}

	const GRectangleOriented& GRectangleOriented::operator = (const GRectangleOriented& Other)
	{
		Center = Other.Center;
		Dimension = Other.Dimension;
		Right = Other.Right;
		Up = Other.Up;

		return *this;
	}


}